package nfwx.analytics;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 采集参数的一个发送任务
 */

public class GrabSend {
    double _time0; //首次提交本数据时的客户端时间unix时间戳ms
    String _sessionId; //会话ID
    String _type; //会话类型("app": 应用会话, "video": 视频会话)
    String _stat; //JSON格式的统计信息, 随type不同stat格式也不同

    //sig: String, //数字签名, 签名算法为: md5(appId.toUpper() + time0 + time + sessionId.toUpper() + type + secret + stat).toHex().toUpper();

    /**
     * 将会话转换成发送任务
     * @param session
     */
    GrabSend(GrabSession session) throws JSONException {
        _time0 = 0;
        _sessionId = session.sessionId;
        _type = session.sessionType;
        _stat = GrabJSON.toJSONString("", session, true);
        //无需提交
        if (_stat == null) return;
        //清除所有事件
        session.events.clear();
        //清0使用时间
        session.useTimeDelta.setValue(0);
        //重置所有变化量
        session.resetChanged();
    }

    /**
     * 从JSON对象中提取发送任务
     * @param j
     */
    GrabSend(JSONObject j) throws JSONException {
        _time0 = j.optDouble("time0", 0.0);
        _sessionId = j.getString("sessionId");
        _type = j.getString("type");
        _stat = j.getString("stat");
    }

    /**
     * 判断任务是否有效，是否需要提交
     * @return
     */
    boolean getValid()
    {
        return _stat != null;
    }

    /**
     * 将发送任务序列化成JSON
     * @return
     */
    JSONObject toJSON() throws JSONException {
        JSONObject j=new JSONObject();
        j.put("time0", _time0);
        j.put("sessionId", _sessionId);
        j.put("type", _type);
        j.put("stat", _stat);
        return j;
    }

    /**
     * 生成用于提交到服务器的参数列表
     * @param appId 应用ID
     * @param secret 应用密钥
     * @return
     */
    Map<String, String> makeSubmitParams(String appId, String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        Map<String, String> r = new HashMap<>();
        if (_time0 == 0) { //尚未提交
            _time0 = (new Date()).getTime();
        }
        r.put("appId", appId.toUpperCase());
        r.put("time0", ""+(long)_time0);
        r.put("time", ""+(new Date()).getTime());
        r.put("sessionId", _sessionId);
        r.put("type", _type);
        r.put("stat", _stat);


        String plain=appId.toUpperCase() + r.get("time0") + r.get("time") + _sessionId.toUpperCase() + _type + secret + r.get("stat");
        String sig = MD5(plain);
        r.put("sig", sig);
        return r;
    }

    public static String bytesToHex(byte[] bytes)
    {
        final String HEX = "0123456789ABCDEF";
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte b : bytes)
        {
            sb.append(HEX.charAt((b >> 4) & 0x0f));
            sb.append(HEX.charAt(b & 0x0f));
        }

        return sb.toString();
    }

    public static String MD5(String s) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        MessageDigest md5= MessageDigest.getInstance("MD5");
        return bytesToHex(md5.digest(s.getBytes("utf-8")));
    }
}
